﻿using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Singer.Framework.CoreDI;

/// <summary>
/// 依赖注入 拓展
/// </summary>
public static class CoreDIServiceExtensions
{
    /// <summary>
    /// 将程序集带有CoreDI特性的服务自动注入到DI容器
    /// </summary>
    public static void AddCoreDIServices(this IServiceCollection services, params Assembly[] assemblies)
    {
        foreach (var assembly in assemblies)
        {
            Dictionary<Type, IEnumerable<CoreDIAttribute>> dic = assembly.GetTypes().ToDictionary(x => x, x => x.GetCustomAttributes<CoreDIAttribute>());
            foreach (var item in dic)
            {
                Type type = item.Key;
                IEnumerable<CoreDIAttribute> attributes = item.Value;
                if (attributes.Count() == 0)
                    continue;
                foreach (CoreDIAttribute di in attributes)
                {
                    if (di.InterfaceType != null && !type.GetInterfaces().Any(x => x == di.InterfaceType))
                        throw new Exception($"【CoreDI】 The Service '{type?.Name}' can not be resolving to the Service '{di.InterfaceType.Name}' ");
                    services.Replace(new ServiceDescriptor(di.InterfaceType ?? type, type, di.ServiceLifetime));
                }
            }
        }
    }
}
